package com.qgs.secsgem.secs.controller;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.HexUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qgs.secsgem.common.utils.CommonFunction;
import com.qgs.secsgem.secs.SecsException;
import com.qgs.secsgem.secs.SecsMessage;
import com.qgs.secsgem.secs.constant.EventNameConstant;
import com.qgs.secsgem.secs.controller.pid24a.PID24aMESToEQController;
import com.qgs.secsgem.secs.entity.MesRequestMessage;
import com.qgs.secsgem.secs.entity.common.*;
import com.qgs.secsgem.secs.entity.eventBody.*;
import com.qgs.secsgem.secs.eq.SECSCommand;
import com.qgs.secsgem.secs.eq.runnable.PID10Runnable;
import com.qgs.secsgem.secs.eq.runnable.PID24aRunnable;
import com.qgs.secsgem.secs.gem.COMMACK;
import com.qgs.secsgem.secs.gem.Clock;
import com.qgs.secsgem.secs.gem.OFLACK;
import com.qgs.secsgem.secs.gem.ONLACK;
import com.qgs.secsgem.secs.hsmsss.HsmsSsCommunicator;
import com.qgs.secsgem.secs.secs2.Secs2Exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @Desc: ""
 * @Author: caixiang
 * @DATE: 2024/8/22 15:44
 */
public class SecsSerivce {

    private static final Logger logger = LoggerFactory.getLogger(PID24aMESToEQController.class);

    public static List<ValueNode> get(JSONArray argList){
        List<ValueNode> set = new ArrayList<>();

        for(int i=0;i<argList.size();i++){
            if(argList.get(i) == null){
                continue;
            }
            JSONObject j = (JSONObject) argList.get(i);
            String type = j.getString("f");
            if(!type.equals("L")){
                set.add(new ValueNode(j.getString("f"),j.get("v").toString()));

            }else {
                //当嵌套里面还有嵌套，，这里顺序错了，修复一下。
                JSONArray array = j.getJSONArray("v");
                set.add(new ValueNode("List",get(array)));
            }
        }
        return set;
    }

    public static void doS1F1(HsmsSsCommunicator comm) throws Secs2Exception, InterruptedException, SecsException {
        SECSCommand.areYouThere(comm);
    }
    public static List<ResVIDNode> doS1F3(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException {
        S1F3MesRequestBody jsonObject = JSONObject.parseObject(bodyString,S1F3MesRequestBody.class);
        List<String> vidList = jsonObject.getSvList();

        Optional<SecsMessage> ss = SECSCommand.queryEQPStatus(jsonObject.getSvList(), jsonObject.getSvType(),comm);

        //todo S1F3 有问题，下周来检查一下
        //解析secsMessage   开始
        JSONObject secsObject = JSONObject.parseObject(ss.get().secs2().toJson());
        List<ResVIDNode> body = new ArrayList<>();
        if(secsObject.getString("f").equals("L")){
            JSONArray v = secsObject.getJSONArray("v");
            for(int i= 0;i<vidList.size();i++){
                JSONObject rsp = v.getJSONObject(i);
                String vid = vidList.get(i);
//                String valueType = Objects.equals(rsp.getString("f"), "L") ? "List":rsp.getString("f");
                String valueType = rsp.getString("f");

                if(valueType.equals("L")){
                    body.add(new ResVIDNode(vid,valueType,get(rsp.getJSONArray("v"))));
                }else {
                    //如果是单体变量就直接这样就行了
                    body.add(new ResVIDNode(vid,valueType,rsp.get("v").toString()));
                }
            }
        }
        //解析secsMessage   结束
        return body;
    }
    public static List<ResS1F11VIDNode> doS1F11(HsmsSsCommunicator comm, String bodyString) throws InterruptedException, SecsException {
        List<String> vidList = new ArrayList<>();

        JSONObject jsonObject = JSONObject.parseObject(bodyString);
        String vidType = jsonObject.getString("vidType");
        JSONArray o = jsonObject.getJSONArray("vidList");
        for(int i=0;i<o.size();i++){
            vidList.add(o.getString(i));
        }

        Optional<SecsMessage> ss = SECSCommand.querySVNameList(vidList, PID10Runnable.VID_Type, comm);;

        //解析secsMessage   开始
        JSONObject secsObject = JSONObject.parseObject(ss.get().secs2().toJson());
        //SVID  20,3X,5X
        //SVNAME 20
        //UNITS 20
        List<ResS1F11VIDNode> body = new ArrayList<>();
        if(secsObject.getString("f").equals("L")){
            JSONArray v = secsObject.getJSONArray("v");
            for(int i= 0;i<v.size();i++){

                JSONArray v1 = v.getJSONObject(i).getJSONArray("v");
                JSONObject svid = v1.getJSONObject(0);

                String svidType = svid.getString("f");
                String svidValue = svid.getJSONArray("v").get(0).toString();

                JSONObject svname = v1.getJSONObject(1);
                String svnameValue = svname.getString("v");

                JSONObject units = v1.getJSONObject(2);
                String unitsValue = units.getString("v");

                body.add(new ResS1F11VIDNode(svidValue,svidType,svnameValue,unitsValue));
            }
        }
        //解析secsMessage   结束
        return body;
    }

    public static COMMACK doS1F13(HsmsSsCommunicator comm) throws Secs2Exception, InterruptedException, SecsException {
        return SECSCommand.establishCommunications(PID24aRunnable.comm);
    }

    public static OFLACK doS1F15(HsmsSsCommunicator comm) throws Secs2Exception, InterruptedException, SecsException {
        return SECSCommand.requestOffLine(PID24aRunnable.comm);
    }

    public static ONLACK doS1F17(HsmsSsCommunicator comm) throws Secs2Exception, InterruptedException, SecsException {
        return SECSCommand.requestOnLine(PID24aRunnable.comm);
    }

    public static List<ResVIDNode> doS2F13(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {
        List<String> ecidList = new ArrayList<>();

        JSONObject jsonObject = JSONObject.parseObject(bodyString);
        String ecidtype = jsonObject.getString("ecidType");
        JSONArray o = jsonObject.getJSONArray("ecidList");

        for(int i=0;i<o.size();i++){
            ecidList.add(o.getString(i));
        }

        Optional<SecsMessage> ss = SECSCommand.eqConstantReq(ecidList,ecidtype,comm);

        //解析secsMessage   开始
        //todo 这里还要在检查一下
        JSONObject secsObject = JSONObject.parseObject(ss.get().secs2().toJson());
        List<ResVIDNode> body = new ArrayList<>();
        if(secsObject.getString("f").equals("L")){
            JSONArray v = secsObject.getJSONArray("v");
            for(int i= 0;i<ecidList.size();i++){
                JSONObject rsp = v.getJSONObject(i);
                String vid = ecidList.get(i);
//                String valueType = Objects.equals(rsp.getString("f"), "L") ? "List":rsp.getString("f");
                String valueType = rsp.getString("f");

                if(valueType.equals("L")){
                    body.add(new ResVIDNode(vid,valueType,get(rsp.getJSONArray("v"))));
                }else {
                    //如果是单体变量就直接这样就行了
                    body.add(new ResVIDNode(vid,valueType,rsp.get("v").toString()));
                }
            }
        }
        //解析secsMessage   结束
        return body;
    }

    //return EAC; 1byte ; 0=ack 0!=异常
    public static String doS2F15(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {
        List<ECNode> ecidList = new ArrayList<>();

        JSONObject jsonObject = JSONObject.parseObject(bodyString);
        String ecidtype = jsonObject.getString("ecidType");
        JSONArray o = jsonObject.getJSONArray("ecidList");

        for(int i=0;i<o.size();i++){
            JSONObject j = o.getJSONObject(i);
            ecidList.add(new ECNode(j.getString("ecid"),j.getString("ecv"),j.getString("ecvType")));
            //ecidList.add(o.getString(i));
        }

        Optional<SecsMessage> ss = SECSCommand.newEquipmentConstantSend(ecidList,ecidtype,comm);

        //解析secsMessage   开始
        //todo 这里还要在检查一下
        JSONObject secsObject = JSONObject.parseObject(ss.get().secs2().toJson());

        return secsObject.getJSONArray("v").get(0).toString();
    }
    public static Clock doS2F17(HsmsSsCommunicator comm) throws Secs2Exception, InterruptedException, SecsException {
        return SECSCommand.dateAndTimeRequest(PID24aRunnable.comm);
    }

    //return <TIAACK>  ok = 0 ; noOk !=0
    public static String doS2F23(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {
        List<String> ecidList = new ArrayList<>();

        TraceNode traceNode = JSONObject.parseObject(bodyString, TraceNode.class);
        Optional<SecsMessage> secsMessage = SECSCommand.traceInitialSend(traceNode,comm);
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());
        return secsObject.getJSONArray("v").get(0).toString();
    }

    public static List<ECDetailNode> doS2F29(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {
        List<String> ecidList = new ArrayList<>();

        JSONObject jsonObject = JSONObject.parseObject(bodyString);
        String ecidtype = jsonObject.getString("ecidType");
        JSONArray o = jsonObject.getJSONArray("ecidList");

        for(int i=0;i<o.size();i++){
            ecidList.add(o.getString(i));
        }

        Optional<SecsMessage> ss = SECSCommand.equipmentConstantNameListRequest(ecidList,ecidtype,comm);;

        //解析secsMessage   开始
        //todo 这里还要在检查一下
        JSONObject secsObject = JSONObject.parseObject(ss.get().secs2().toJson());

        List<ECDetailNode> body = new ArrayList<>();
        if(secsObject.getString("f").equals("L")){
            JSONArray v = secsObject.getJSONArray("v");
            for(int i= 0;i<v.size();i++){
                JSONObject rsp = v.getJSONObject(i);
                if(rsp.getString("f").equals("L")){
                    JSONArray detail = rsp.getJSONArray("v");
                    //20 3X 5X
                    String ecidType = detail.getJSONObject(0).getString("f");
                    String ecid = detail.getJSONObject(0).getJSONArray("v").get(0).toString();


                    String ecName = detail.getJSONObject(1).getString("v");

                    String ecMinType = detail.getJSONObject(2).getString("f");
                    String ecMin = detail.getJSONObject(2).getJSONArray("v").get(0).toString();

                    String ecMaxType = detail.getJSONObject(3).getString("f");
                    String ecMax = detail.getJSONObject(3).getJSONArray("v").get(0).toString();

                    String ecDefType = detail.getJSONObject(4).getString("f");
                    String ecDef = detail.getJSONObject(4).getJSONArray("v").get(0).toString();


                    String units = detail.getJSONObject(5).getString("v");

                    body.add(new ECDetailNode(ecid,ecidType,ecName,ecMin,ecMinType,ecMax,ecMaxType,ecDef,ecDefType,units));
                }
            }
        }
        //解析secsMessage   结束
        return body;
    }

    public static boolean doS2F33(HsmsSsCommunicator comm,S2F33MesRequestBody jsonObject) throws InterruptedException, SecsException, Secs2Exception {

        Optional<SecsMessage> secsMessage = SECSCommand.defineReport(jsonObject.getReportNodes(),comm);

        //解析secsMessage   开始
        //reutrn <DRACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());

        return secsObject.getJSONArray("v").get(0).toString().equals("0")?true:false;
    }

    public static boolean doS2F35(HsmsSsCommunicator comm,S2F35MesRequestBody jsonObject) throws InterruptedException, SecsException, Secs2Exception {

        Optional<SecsMessage> secsMessage = SECSCommand.linkEventReport(jsonObject.getReportNodes(),comm);

        //解析secsMessage   开始
        //reutrn <LRACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());

        return secsObject.getJSONArray("v").get(0).toString().equals("0")?true:false;
    }
    public static boolean doS2F37(HsmsSsCommunicator comm,S2F37MesRequestBody jsonObject) throws InterruptedException, SecsException, Secs2Exception {

        Optional<SecsMessage> secsMessage = SECSCommand.enableEventReport(jsonObject.getCeids(), jsonObject.getCeidType(), jsonObject.getCeed(),comm);;

        //解析secsMessage   开始
        //reutrn <ERACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());

        return secsObject.getJSONArray("v").get(0).toString().equals("0")?true:false;
    }

    public static S2F42MesResponseBody doS2F41(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {


        S2F41MesRequestBody jsonObject = JSONObject.parseObject(bodyString, S2F41MesRequestBody.class);
        Optional<SecsMessage> secsMessage = SECSCommand.hostCommandSend(jsonObject.getRcmdNode(),comm);

        //解析secsMessage   开始
        //reutrn <ERACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());

        return new S2F42MesResponseBody(secsObject.getJSONArray("v").getJSONObject(0).getJSONArray("v").get(0).toString(), secsObject.getJSONArray("v").get(1).toString());
    }

    public static S2F42MesResponseBody doS2F49(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {


        S2F49MesRequestBody jsonObject = JSONObject.parseObject(bodyString, S2F49MesRequestBody.class);
        Optional<SecsMessage> secsMessage = SECSCommand.enhancedRemoteCommand(jsonObject.getErcmdNode(),comm);

        //解析secsMessage   开始
        //reutrn <ERACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());

        return new S2F42MesResponseBody(secsObject.getJSONArray("v").getJSONObject(0).getJSONArray("v").get(0).toString(), secsObject.getJSONArray("v").get(1).toString());
    }
    public static int convertByteArrayToInt(int[] ints) {
        int res = 0;
        if(ints[0] == 1){
            res+=128;
        }
        if(ints[1] == 1){
            res+=64;
        }
        if(ints[2] == 1){
            res+=32;
        }
        if(ints[3] == 1){
            res+=16;
        }
        if(ints[4] == 1){
            res+=8;
        }
        if(ints[5] == 1){
            res+=4;
        }
        if(ints[6] == 1){
            res+=2;
        }
        if(ints[7] == 1){
            res+=1;
        }

        return res;
    }
    /**
     * 把byte转为字符串的bit
     */
    public static String byteToBit(byte b) {
        return ""
                + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
                + (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
                + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
                + (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
    }
    private static ALCD parseALCD(String ss) {
        Character c1;
        Character c2;
        if(ss.length()!=2){
            c1 = '0';
            c2 = ss.charAt(0);
        }else {
            c1 = ss.charAt(0);
            c2 = ss.charAt(1);
        }



        Byte s = HexUtil.decodeHex(c1.toString())[0];
        String s1 = byteToBit(s);
        char[] s11 = s1.toCharArray();

        Byte d = HexUtil.decodeHex(c2.toString())[0];
        String d1 = byteToBit(d);
        char[] d11 = d1.toCharArray();

        int[] res = new int[8];
        res[0] = s11[4]=='1'? 1: 0;
        res[1] = s11[5]=='1'? 1: 0;
        res[2] = s11[6]=='1'? 1: 0;
        res[3] = s11[7]=='1'? 1: 0;

        res[4] = d11[4]=='1'? 1: 0;
        res[5] = d11[5]=='1'? 1: 0;
        res[6] = d11[6]=='1'? 1: 0;
        res[7] = d11[7]=='1'? 1: 0;
        String category = "";
        String alarmStatus = "0";
        if(res[0] == 1){
            alarmStatus = "1";
        }
        res[0] = (byte) 0;

        int i = convertByteArrayToInt(res);
        if(i==0){
            category = "Not used";
        }else if(i==1){
            category = "Personal safety";
        }else if(i == 2 ){
            category = "Equipment safety";
        }else if(i == 3 ){
            category = "Parameter control warning";
        }else if(i == 4 ){
            category = "Parameter control error";
        }else if(i == 5 ){
            category = "Irrecoverable error";
        }else if(i == 6 ){
            category = "Equipment status warning";
        }else if(i == 7 ){
            category = "Attention flags";
        }else if(i == 8 ){
            category = "Data integrity";
        }else {
            //如果i>8 那是保留的，就得问 设备商了。
            category = "Other categories";
        }

        ALCD alcd = new ALCD();
        alcd.setAlarmCategory(category);
        alcd.setAlarmState(alarmStatus);
        alcd.setAlcd(ss);
        return alcd;
    }
    //return ACKC5
    public static String doS5F3(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {


        S5F3MesRequestBody jsonObject = JSONObject.parseObject(bodyString, S5F3MesRequestBody.class);
        Optional<SecsMessage> secsMessage = SECSCommand.alarmEDManager(jsonObject.getAlids(), jsonObject.getAlidType(), jsonObject.getOnff(),comm);

        //解析secsMessage   开始
        //reutrn <ERACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());

        return secsObject.getJSONArray("v").get(0).toString();
    }

    public static List<AlarmBody> doS5F5(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {


        S5F5MesRequestBody jsonObject = JSONObject.parseObject(bodyString, S5F5MesRequestBody.class);
        Optional<SecsMessage> secsMessage = SECSCommand.alarmList(jsonObject.getAlids(), jsonObject.getAlidType(),comm);

        //解析secsMessage   开始
        //reutrn <ERACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());


        List<AlarmBody> body = new ArrayList<>();
        if(secsObject.getString("f").equals("L")){
            JSONArray v = secsObject.getJSONArray("v");
            for(int i= 0;i<v.size();i++){
                JSONObject rsp = v.getJSONObject(i);
                if(rsp.getString("f").equals("L")){
                    JSONArray detail = rsp.getJSONArray("v");
                    // alcd(10 byte)
                    String alcd = detail.getJSONObject(0).getJSONArray("v").get(0).toString();

                    //3x 5x

                    String alid = detail.getJSONObject(1).getJSONArray("v").get(0).toString();

                    //altx (20 String)
                    String altx = detail.getJSONObject(2).getString("v");


                    body.add(new AlarmBody(parseALCD(alcd.toString()),Integer.parseInt(alid),altx));
                }
            }
        }


        return body;
    }

    public static boolean doS6F23(HsmsSsCommunicator comm,S6F23MesRequestBody jsonObject) throws InterruptedException, SecsException, Secs2Exception {


        Optional<SecsMessage> secsMessage = SECSCommand.requestSpooledData(jsonObject.getRsdc(),comm);
        //解析secsMessage   开始
        //reutrn <RSDA>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());
        return secsObject.getJSONArray("v").get(0).toString().equals("0")?true:false;
    }

    public static List<String> doS7F19(HsmsSsCommunicator comm) throws InterruptedException, SecsException, Secs2Exception {




        Optional<SecsMessage> secsMessage = SECSCommand.currentEPPDRequest(comm);
        //解析secsMessage   开始
        //reutrn <ERACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());

        List<String> body = new ArrayList<>();
        if(secsObject.getString("f").equals("L")){
            JSONArray v = secsObject.getJSONArray("v");
            for(int i= 0;i<v.size();i++){
                JSONObject rsp = v.getJSONObject(i);
                body.add(rsp.getString("v"));
            }
        }



        return body;
    }

    public static PPIDBody doS7F5(HsmsSsCommunicator comm,String bodyString) throws InterruptedException, SecsException, Secs2Exception {


        S7F5MesRequestBody jsonObject = JSONObject.parseObject(bodyString, S7F5MesRequestBody.class);

        Optional<SecsMessage> secsMessage = SECSCommand.processProgramRequest(jsonObject.getPpid(),jsonObject.getPpidType(),comm);
        //解析secsMessage   开始
        //reutrn <ERACK>  ack = 0 ; noack != 0
        JSONObject secsObject = JSONObject.parseObject(secsMessage.get().secs2().toJson());


        if(secsObject.getString("f").equals("L")){
            JSONArray v = secsObject.getJSONArray("v");
            JSONObject ppid = v.getJSONObject(0);
            String ppidType = ppid.getString("f");
            String ppidValue = ppid.getString("v");

            JSONObject ppbody = v.getJSONObject(1);
            String ppbodyType = ppbody.getString("f");
            String ppbodyValue = ppbody.getString("v");
            return new PPIDBody(ppidValue,ppidType,ppbodyValue,ppbodyType);
        }
        return null;
    }
}
